package com.wlps.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wlps.contant.Contant;
import com.wlps.entity.CommodityWarehouse;
import com.wlps.entity.Warehouse;
import com.wlps.mapper.WarehouseMapper;
import com.wlps.result.ResultPageVo;
import com.wlps.result.ResultUtils;
import com.wlps.result.ResultVo;
import com.wlps.service.ICommodityWarehouseService;
import com.wlps.service.IWarehouseService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wlps.vo.sendcenter.warehouse.WarehouseAddVo;
import com.wlps.vo.sendcenter.warehouse.WarehouseUpdateVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 库房表（warehouse）
 * (1.当实际到货数量和订购数量不相符时，中心库房管理员修改实际到货数量)
 * 服务实现类
 * </p>
 *
 * @author ZWYZY
 * @since 2020-07-31
 */
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class WarehouseServiceImpl extends ServiceImpl<WarehouseMapper, Warehouse> implements IWarehouseService, InitializingBean {
    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    ICommodityWarehouseService commodityWarehouseService;

    @Override
    public void afterPropertiesSet() throws Exception {
        initWarehouse();
    }

    /**
     * 初始化缓存
     */
    void initWarehouse() {
        List<Warehouse> warehouseList;
        if (redisTemplate.hasKey(Contant.WAREHOUSES_KEY)) {
            warehouseList = (List<Warehouse>) redisTemplate.opsForValue().get(Contant.WAREHOUSES_KEY);
        } else {
            warehouseList = baseMapper.selectList(null);
            redisTemplate.opsForValue().set(Contant.WAREHOUSES_KEY, warehouseList,5, TimeUnit.MINUTES);
            log.info("初始化所有库房（中心库房）-------存入缓存数据");
        }
        if (!redisTemplate.hasKey(Contant.WAREHOUSELIST_KEY)) {
            redisTemplate.opsForList().rightPushAll(Contant.WAREHOUSELIST_KEY, warehouseList);
            redisTemplate.expire(Contant.WAREHOUSELIST_KEY,5,TimeUnit.MINUTES);
            log.info("初始化库房列表（中心库房）--------存入缓存数据");
        }
    }

    @Override
    public ResultPageVo<List<Warehouse>> getWarehouse(int pageNum, int pageSize, String name) {
        initWarehouse();
        //总条数
        long count;
        List<Warehouse> warehouseList;

        if (name == null) {
            //不是条件查询，redis
            count = (Long) redisTemplate.opsForList().size(Contant.WAREHOUSELIST_KEY);
            //当前页从第几条开始查
            long fromNum = pageSize * (pageNum - 1);
            if (fromNum >= count) {
                warehouseList = (List<Warehouse>) redisTemplate.opsForList().range(Contant.WAREHOUSELIST_KEY, 0, count);

            } else {
                //当前页最后第几条
                long toNum = fromNum + pageSize >= count ? count : fromNum + pageSize;
                warehouseList = (List<Warehouse>) redisTemplate.opsForList().range(Contant.WAREHOUSELIST_KEY, fromNum, toNum-1);
            }
            //当前页最后第几条

//            RedisConfig.returnJedis(jedis);

        } else {//条件查询，mysql
            Page<Warehouse> warehousePage = new Page<>(pageNum, pageSize);
            LambdaQueryWrapper<Warehouse> queryWrapper = new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getName, name);
            IPage<Warehouse> page = this.baseMapper.selectPage(warehousePage, queryWrapper);
            warehouseList = page.getRecords();
            count = page.getSize();
        }

        //分页返回值封装
        ResultPageVo resultPageVo = new ResultPageVo("响应成功", 200, (long) pageSize, (long) pageNum, count, warehouseList);

        return resultPageVo;
    }

    @Override
    public ResultVo addWarehouse(WarehouseAddVo warehouseAddVo) {
        Warehouse warehouse = new Warehouse();
        BeanUtils.copyProperties(warehouseAddVo, warehouse);
        baseMapper.insert(warehouse);
        warehouseUpdateCache();
        return ResultUtils.success("创建库房成功，亲");
    }

    @Override
    public ResultVo deleteWarehouse(Long id) {
        Warehouse warehouse = baseMapper.selectById(id);
        if (warehouse == null) {
            return ResultUtils.error("库房编号查询不到，请输入正确的库房编号，亲", 40000);
        }
        baseMapper.deleteById(id);
        warehouseUpdateCache();
        return null;
    }

    @Override
    public ResultVo updateWarehouse(WarehouseUpdateVo warehouseUpdateVo) {
        if (baseMapper.selectById(warehouseUpdateVo.getId()) == null) {
            return ResultUtils.error("库房编号查询不到，请输入正确的库房编号，亲", 40000);
        }
        List<CommodityWarehouse> commodityWarehouseList = commodityWarehouseService.list(new QueryWrapper<CommodityWarehouse>().lambda().eq(CommodityWarehouse::getWarehouseId, warehouseUpdateVo.getId()));
        Long maxNumber = commodityWarehouseList.stream().mapToLong(CommodityWarehouse::getMaximumCommodity).sum();

        if (warehouseUpdateVo.getMaximumWarehouse() - maxNumber <= 0) {
            return ResultUtils.error("当前设置的库房最大值{" + warehouseUpdateVo.getMaximumWarehouse() + "}低于目前仓库存放商品最大存量总和{" + maxNumber + "}", 40001);
        }
        Warehouse warehouse = new Warehouse();
        BeanUtils.copyProperties(warehouseUpdateVo, warehouse);
        baseMapper.updateById(warehouse);
        warehouseUpdateCache();
        return ResultUtils.success("修改库房信息成功，亲");
    }

    @Override
    public ResultVo<Warehouse> getWarehouseById(Long id) {
        Warehouse warehouse = baseMapper.selectById(id);
        if (warehouse == null) {
            return ResultUtils.error("库房编号查询不到，请输入正确的库房编号，亲", 40000);
        }
        return ResultUtils.success("查询成功，亲", warehouse);
    }


    /**
     * 更新缓存
     */
    @Async
    public void warehouseUpdateCache() {
        List<Warehouse> warehouseList = baseMapper.selectList(null);
        redisTemplate.opsForValue().set(Contant.WAREHOUSES_KEY, warehouseList,5,TimeUnit.MINUTES);
        redisTemplate.delete(Contant.WAREHOUSELIST_KEY);
        redisTemplate.opsForList().rightPushAll(Contant.WAREHOUSELIST_KEY, warehouseList);
        redisTemplate.expire(Contant.WAREHOUSELIST_KEY,5,TimeUnit.MINUTES);
        log.info("所有库房(中心库房)）-------更新缓存数据");
    }
}
